package net.nampham.visioncontrol.model3d;

public class Plane {
	float a;
	float b;
	float c;
	float d;
	public Plane(Vec3 p0, Vec3 p1, Vec3 p2){
		a = p0.y * (p1.z - p2.z) + p1.y * (p2.z - p0.z) + p2.y * (p0.z - p1.z);
		b = p0.z * (p1.x - p2.x) + p1.z * (p2.x - p0.x) + p2.z * (p0.x - p1.x);
		c = p0.x * (p1.y - p2.y) + p1.x * (p2.y - p0.y) + p2.x * (p0.y - p1.y);
		d = -( p0.x * (p1.y * p2.z - p2.y * p1.z) 
				+ p1.x * (p2.y * p0.z - p0.y * p2.z) 
				+ p2.x * (p0.y * p1.z - p1.y * p0.z));
	}
	
	public enum Plane2Line{
		ALL_LINE,
		PARALLEL,
		POINT
	}
	
	public class Plane2LineResult{
		Plane2Line type;
		Vec3 p;
	}
	
	public Plane2LineResult intersect(Line3D line){
		Plane2LineResult ret = new Plane2LineResult();
		float den = a*line.dir.x + b*line.dir.y
			+ c*line.dir.z;
		float num = a*line.p.x + b*line.p.y
        	+ c*line.p.z + d;
		if (den==0){
			if (num==0){
				ret.type = Plane2Line.ALL_LINE;
			}else{
				ret.type = Plane2Line.PARALLEL;
			}
		}else{
			ret.type = Plane2Line.POINT;
			float num_div_den = num/den;
			ret.p = new Vec3(
						line.p.x - num_div_den * line.dir.x,
						line.p.y - num_div_den * line.dir.y,
						line.p.z - num_div_den * line.dir.z
					);
		}
		return ret;
	}
	
	public enum Plane2Plane{
		IDENTICAL,
		LINE
	}
	
	public class Plane2PlaneResult{
		Plane2Plane type;
		Line3D l;
	}
}
